package com.neusoft.neuiotms.dcam.fixed.converter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.dto.AbstractConverter;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.utils.id.BaseIdGenerator;
import com.neusoft.neuiotms.dcam.common.converter.LocationConverter;
import com.neusoft.neuiotms.dcam.common.model.Location;
import com.neusoft.neuiotms.dcam.common.repository.LocationRepository;
import com.neusoft.neuiotms.dcam.fixed.dto.InventoryDutyDTO;
import com.neusoft.neuiotms.dcam.fixed.model.AssetType;
import com.neusoft.neuiotms.dcam.fixed.model.ConnectionRelation;
import com.neusoft.neuiotms.dcam.fixed.model.InventoryDuty;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetTypeRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.InventoryDutyRepository;

@Component
public class InventoryDutyConverter extends AbstractConverter<InventoryDuty, InventoryDutyDTO> {

    @Autowired
    private InventoryDutyRepository inventoryDutyRepository;
    @Autowired
    private LocationConverter locationConverter;
    @Autowired
    private AssetTypeConverter assetTypeConverter;
    @Autowired
    private ConnectionRelationConverter relationConverter;
    @Autowired
    private BaseIdGenerator dutyCodeGenerator;
    @Autowired
    private LocationRepository locationRepository;
    @Autowired
    private AssetTypeRepository assetTypeRepository;

    @Override
    public InventoryDuty toModel(final InventoryDutyDTO dto) {

        InventoryDuty model;
        if (dto.isNew()) {
            model = new InventoryDuty();
            model.setCode(this.dutyCodeGenerator.generateCode());
        } else {
            model = this.inventoryDutyRepository.getOne(dto.getId());
        }

        model.setName(dto.getName());
        model.setStatus(dto.getStatus());
        model.setUserId(dto.getUserId());
        model.setUserName(dto.getUserName());
        model.setUpdateTime(new Date());

        // 位置
        model.getLocations().clear();
        dto.getLocationCodes().stream().map(code -> {
            Location location = null;
            try {
                location = this.locationRepository.findByCode(code);
            } catch (final Exception e) {
                throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {code });
            }
            return location;
        }).filter(m -> null != m).forEach(model.getLocations()::add);

        // 类型
        model.getAssetTypes().clear();
        dto.getAssetTypeCodes().stream().map(code -> {
            AssetType type = null;
            try {
                type = this.assetTypeRepository.findByCode(code);
            } catch (final Exception e) {
                throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {code });
            }
            return type;
        }).filter(m -> null != m).forEach(model.getAssetTypes()::add);

        // 组织

        final List<ConnectionRelation> list = new ArrayList<>();
        for (int j = 0; j < dto.getOrgCodes().size(); j++) {
            final ConnectionRelation conModel = new ConnectionRelation();
            conModel.setBusinessId(dto.getOrgCodes().get(j));
            conModel.setName(dto.getOrgNames().get(j));
            list.add(conModel);
        }

        model.getOrgRelation().clear();
        list.forEach(model.getOrgRelation()::add);

        return model;
    }

    @Override
    public InventoryDutyDTO toDTO(final InventoryDuty model, final boolean forListView) {

        final InventoryDutyDTO dto = new InventoryDutyDTO();

        dto.setId(model.getId());
        dto.setName(model.getName());
        dto.setStatus(model.getStatus());
        dto.setUserId(model.getUserId());
        dto.setUserName(model.getUserName());
        dto.setCode(model.getCode());
        dto.setUpdateTime(model.getUpdateTime());

        if (!forListView) {
            model.getLocations().stream().map(m -> this.locationConverter.toDTO(m)).forEach(dto.getLocations()::add);
            model.getAssetTypes().stream().map(m -> this.assetTypeConverter.toDTO(m)).forEach(dto.getAssetTypes()::add);
            model.getOrgRelation().stream().map(m -> this.relationConverter.toDTO(m))
                    .forEach(dto.getOrgRelation()::add);
        }

        model.getLocations().stream().map(m -> m.getCode()).forEach(dto.getLocationCodes()::add);
        model.getAssetTypes().stream().map(m -> m.getCode()).forEach(dto.getAssetTypeCodes()::add);
        model.getOrgRelation().stream().map(m -> m.getBusinessId()).forEach(dto.getOrgCodes()::add);
        model.getOrgRelation().stream().map(m -> m.getName()).forEach(dto.getOrgNames()::add);

        if (null != model.getInventoryPlan()) {
            dto.setInventoryPlanId(model.getInventoryPlan().getId());
            dto.setInventoryPlanName(model.getInventoryPlan().getName());
            dto.setInventoryPlanCode(model.getInventoryPlan().getCode());
            dto.setInventoryPlanStatus(model.getInventoryPlan().getStatus());
        }
        return dto;
    }

}
